package tech.senri.iot.socket.service.socket

import io.netty.buffer.ByteBuf
import tech.senri.iot.socket.model.*
import tech.senri.iot.socket.service.util.toBits
import java.nio.charset.Charset

object Decoder
{

    private val updatePriceInventoryResponse = Pair(0x71, 0xff)
    private val updateAislesCapacityResponse = Pair(0x10, 0x0f)
    private val updateDiscountResponse = Pair(0x10, 0x10)
    private val updateMergeAisleResponse = Pair(0x10, 0x11)
    private val deviceStateResponse = Pair(0x70, 0)
    private val simStateResponse = Pair(0x20, 0x01)
    private val discountAmountResponse = Pair(0x20, 0x02)
    private val aislesCapacityResponse = Pair(0x20, 0x06)
    private val receivableResponse = Pair(0x71, 0x01)
    private val refundResponse = Pair(0x71, 0x02)
    private val deliverCommoditySuccessResponse = Pair(0x71, 0x03)
    private val deliverCommodityFailResponse = Pair(0x71, 0xE3)
    private val scanQRCodeInfoResponse = Pair(0x81, 0x02)
    fun decode(code: Pair<Int, Int>,
               deviceId: String,
               dateTime: ByteArray,
               buffer: ByteBuf): ResponseMessage?
    {
        var result: ResponseMessage? = null
        when (code)
        {
            updatePriceInventoryResponse,
            updateAislesCapacityResponse,
            updateDiscountResponse,
            updateMergeAisleResponse           ->
            {
                result = IsSuccessResponse().apply {
                    success = buffer.readShort().toInt() == 1
                }
            }
            deviceStateResponse                ->
            {
                result = DeviceStateResponse()
                result.deviceVersion = buffer.readCharSequence(15, Charset.defaultCharset()).toString()
                val count = buffer.readByte().toInt()
                result.aisleCount = count
                val commodityWayStatus = ByteArray(count)
                val inventorys = ByteArray(count)
                val prices = ByteArray(count)
                buffer.readBytes(commodityWayStatus)
                buffer.readBytes(inventorys)
                buffer.readBytes(prices)
                result.aisleStatus = commodityWayStatus.map { it.toInt() }.toIntArray()
                result.inventorys = inventorys.map { it.toInt() }.toIntArray()
                result.prices = prices.map { it.toInt() }.toIntArray()

                buffer.skipBytes(2)
                val ts = buffer.readByte().toBits()
                result.thermostatic[0] = ts[0] + ts[1]
                result.thermostatic[1] = ts[2] + ts[3]
                result.thermostatic[2] = ts[4] + ts[5]
                result.extBoardState = buffer.readByte().toBits()[1].toInt()
                buffer.skipBytes(3)
                result.netSignal = buffer.readByte().toInt()
                buffer.skipBytes(1)
                val tt = buffer.readByte().toBits()
                result.status = tt[0].toInt()
                result.enableInventory = tt[1].toInt() == 1
                result.enableMerge = tt[2].toInt() == 1
                result.enableDiscount = tt[3].toInt() == 1
                result.temperature1 = buffer.readByte().toInt()
                result.temperature2 = buffer.readByte().toInt()
                result.temperature3 = buffer.readByte().toInt()
            }
            discountAmountResponse             ->
            {
                val ac = buffer.readByte().toInt()
                val da = ByteArray(ac)
                buffer.readBytes(da)
                result = DiscountAmountResponse().apply {
                    discountState = buffer.readByte().toInt()
                    aisleCount = ac
                    discountAmount = da.map { it.toInt() }.toIntArray()
                }
            }

            simStateResponse                   ->
            {
                val dataLen = buffer.readUnsignedByte().toInt()
                result = SimStateResponse().apply {
                    data = buffer.readCharSequence(dataLen, Charset.defaultCharset()).toString()
                }
            }
            aislesCapacityResponse             ->
            {
                val ac = buffer.readUnsignedByte().toInt()
                val da = ByteArray(ac)
                buffer.readBytes(da)
                result = AislesCapacityResponse().apply {
                    aisleCount = ac
                    aislesCapacity = da.map { it.toInt() }.toIntArray()
                }
            }
            receivableResponse, refundResponse ->
            {
                result = SaleDataResponse().apply {
                    amount = buffer.readShort().toInt()
                    tradeMode = buffer.readByte().toInt()
                    aisle = buffer.readUnsignedByte().toInt()
                }
            }
            deliverCommoditySuccessResponse,
            deliverCommodityFailResponse       ->
            {
                result = DeliverCommodityResponse().apply {
                    amount = buffer.readShort().toInt()
                    tradeMode = buffer.readByte().toInt()
                    aisleNo = buffer.readUnsignedByte().toInt()
                    orderNo = buffer.readShort().toInt()
                }
            }
            scanQRCodeInfoResponse             ->
            {
                val dataLen = buffer.readShort().toInt()
                result = ScanQRCodeInfoResponse().apply {
                    QRCodeInfo = buffer.readCharSequence(dataLen, Charset.defaultCharset()).toString()
                }
            }
        }
        return result?.apply {
            this.deviceId = deviceId
            dateTimeData = dateTime
            messageCode = code.first
            funCode = code.second
        }
    }
}

